/**
 * 
 */
package com.cancer.common.util;

import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;

import com.thoughtworks.xstream.XStream;
import com.thoughtworks.xstream.io.xml.XmlFriendlyNameCoder;
import com.thoughtworks.xstream.io.xml.XppDriver;

/**
 * 
 * @company GeekPlus
 * @project beetle
 * @author 刘俊
 * @date 2017年2月9日
 * @since 1.0.0
 */
public class XStreamUtil {
	private static final Map<Class<?>[], XStream> xstreamPool = new ConcurrentHashMap<>();

	private XStreamUtil() {
	}

	private static synchronized XStream getInstance(Class<?>... annos) {
		if (annos == null || annos.length == 0) {
			throw new IllegalArgumentException("annotation cannot be null");
		}
		Set<Class<?>[]> set = xstreamPool.keySet();
		for (Class<?>[] clzz : set) {
			if (clzz.length == annos.length) {
				boolean flag = true;
				for (int i = 0; i < clzz.length; ++i) {
					if (!clzz[i].equals(annos[i])) {
						flag = false;
						break;
					}
				}
				if (flag) {
					return xstreamPool.get(clzz);
				}
			}
		}

		XStream ni = new XStream(new XppDriver(new XmlFriendlyNameCoder("_-", "_")));
//		ni.autodetectAnnotations(true);
		for (Class<?> clz : annos) {
			ni.processAnnotations(clz);
		}
		xstreamPool.put(annos, ni);
		return ni;
	}

	/**
	 * 将对象转换为XML
	 * 
	 * @author 刘俊 2017年2月9日
	 * @param obj		要被转换的JAVABean
	 * @param annos		涉及到的类
	 * @return xml
	 */
	public static String toXML(Object obj, Class<?>... annos) {
		if (annos == null || annos.length == 0) {
			annos = new Class<?>[] {obj.getClass()};
		}
		XStream ins = getInstance(annos);
		return ins.toXML(obj);
	}

	/**
	 * 将XML转换为对象，并根据返回值自动进行强制类型转换
	 * 
	 * @author 刘俊 2017年2月9日
	 * @param xml		xml
	 * @param annos		涉及到的类
	 * @return 
	 */
	@SuppressWarnings("unchecked")
	public static <T> T fromXML(String xml, Class<?>... annos) {
		XStream ins = getInstance(annos);
		return (T) ins.fromXML(xml);
	}

}
